package com.weiqiao.mall.service.impl;

import com.google.gson.Gson;
import com.mingsoft.util.StringUtil;
import com.mongodb.client.model.Filters;
import com.weiqiao.mall.domain.CommodityEntity;
import com.weiqiao.mall.domain.ProductParameterEntity;
import com.weiqiao.mall.domain.VarietyEntity;
import com.weiqiao.mall.repository.ICommodityRepository;
import com.weiqiao.mall.repository.IProductParameterRepository;
import com.weiqiao.mall.service.IProductParameterService;
import com.weiqiao.mall.service.IVarietyService;
import com.weiqiao.utils.MallUtil;
import com.weiqiao.utils.PageUtil;
import com.weiqiao.utils.SecurityUtils;
import com.weiqiao.utils.StringUtils;
import lombok.extern.log4j.Log4j;
import org.apache.commons.collections4.CollectionUtils;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @author xujun
 * @Description: 宝贝参数 service 实现类
 * @Date: 2019/10/26 16:22
 */
@Log4j
@Service("productParameterService")
public class ProductParameterServiceImpl implements IProductParameterService {

    @Autowired
    private IProductParameterRepository productParameterRepository;

    @Autowired
    @Qualifier("VarietyServiceImpl")
    private IVarietyService varietyService;

    @Autowired
    private ICommodityRepository commodityRepository;

    /**
     * 统计总数
     *
     * @param filter 过滤条件
     * @return boolean 返回整型
     */
    @Override
    public int getCount(Bson filter) {
        return productParameterRepository.getParameterCount(filter);
    }

    /**
     * 查询宝贝参数列表
     *
     * @param request
     * @param pageable
     * @return
     */
    @Override
    public Map getProductParameterDataList(HttpServletRequest request, Pageable pageable) {
        Integer companyId = SecurityUtils.getCompanyId();
        Bson filter = Filters.eq("company_id", companyId);
        String parameter_name = request.getParameter("parameter_name");
        if (StringUtils.isNotBlank(parameter_name)) {
            Pattern pattern = Pattern.compile("^.*" + parameter_name + ".*$", Pattern.CASE_INSENSITIVE);
            filter = Filters.and(filter, Filters.eq("parameter_name", pattern));
        }
        String variety_id = MallUtil.getString(request, "variety_id", "");
        // 判断是一级分类 需要查询父类和所有子类
        VarietyEntity firstVariety = varietyService.getVarietyById(Filters.and(Filters.eq("variety_id", variety_id), Filters.eq("company_id", companyId)));
        if (firstVariety != null) {
            List<String> varietyIdList = new ArrayList<>();
            varietyIdList.add(variety_id);
            List<VarietyEntity.SecondVariety> secondVarietyList = firstVariety.getSecondVarietyList();
            if (CollectionUtils.isNotEmpty(secondVarietyList)) {
                for (VarietyEntity.SecondVariety secondVariety : secondVarietyList) {
                    varietyIdList.add(secondVariety.getSecond_variety_id());
                }
            }
            if (CollectionUtils.isNotEmpty(varietyIdList)) {
                filter = Filters.and(filter, Filters.in("variety_id", varietyIdList));
            }
        } else {
            // 如果是某个二级子分类直接查询即可
            if (StringUtils.isNotBlank(variety_id)) {
                filter = Filters.and(filter, Filters.eq("variety_id", variety_id));
            }
        }
        List<String> stringList = productParameterRepository.getParameterList(filter, pageable);
        List<Map> resultList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(stringList)) {
            Gson gson = new Gson();
            for (String str : stringList) {
                ProductParameterEntity productParameterEntity = gson.fromJson(str, ProductParameterEntity.class);
                Map map = new HashMap(6);
                map.put("parameter_id", productParameterEntity.getParameter_id());
                map.put("parameter_name", productParameterEntity.getParameter_name());
                map.put("parameter_sort", productParameterEntity.getParameter_sort());
                map.put("is_required", productParameterEntity.getIs_required());
                map.put("variety_id", productParameterEntity.getVariety_id());
                VarietyEntity varietyEntity = varietyService.getVarietyById(Filters.and(Filters.eq("company_id", companyId), Filters.or(Filters.eq("variety_id", productParameterEntity.getVariety_id()))));
                String pathName = "";
                if (varietyEntity != null) {
                    pathName = varietyEntity.getVariety_name();
                } else {
                    varietyEntity = varietyService.getVarietyById(Filters.and(Filters.eq("company_id", companyId), Filters.eq("secondVarietyList.second_variety_id", productParameterEntity.getVariety_id())));
                    if (varietyEntity != null) {
                        pathName = varietyEntity.getVariety_name();
                        List<VarietyEntity.SecondVariety> secondVarietyList = varietyEntity.getSecondVarietyList();
                        if (CollectionUtils.isNotEmpty(secondVarietyList)) {
                            for (VarietyEntity.SecondVariety secondVariety : secondVarietyList) {
                                if (Objects.equals(productParameterEntity.getVariety_id(), secondVariety.getSecond_variety_id())) {
                                    pathName += ">>" + secondVariety.getSecond_variety_name();
                                    break;
                                }
                            }
                        }
                    }
                }
                map.put("path_name", pathName);
                resultList.add(map);
            }
        }
        return PageUtil.toPage(resultList, this.getCount(filter));
    }


    @Override
    public List<ProductParameterEntity> getProductParameter(HttpServletRequest request) {
        Document doc = new Document();
        doc.append("company_id", SecurityUtils.getCompanyId());
        String variety_id = request.getParameter("variety_id");
        if (StringUtils.isNotBlank(variety_id)) {
            doc.append("variety_id", variety_id);
        }
        List<String> stringList = productParameterRepository.getParameterListByFilter(doc);
        List<ProductParameterEntity> resultList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(stringList)) {
            stringList.forEach(str -> resultList.add(new Gson().fromJson(str, ProductParameterEntity.class)));
        }
        return resultList;
    }

    /**
     * 保存宝贝规格
     *
     * @param request 请求数据
     * @return boolean 返回布尔类型
     */
    @Override
    public ResponseEntity saveProductParameter(HttpServletRequest request) {
        String variety_id = MallUtil.getString(request, "variety_id", "");
        VarietyEntity varietyEntity = varietyService.getVarietyById(Filters.or(Filters.eq("variety_id", variety_id), Filters.eq("secondVarietyList.second_variety_id", variety_id)));
        Map<String, Object> resultMap = new HashMap<>(2);
        if (varietyEntity == null) {
            resultMap.put("result", false);
            resultMap.put("msg", "所属宝贝分类不存在或已被删除，保存失败");
            return new ResponseEntity(resultMap, HttpStatus.OK);
        }
        String parameter_name = MallUtil.getString(request, "parameter_name", "");
        Integer parameter_sort = MallUtil.getInteger(request, "parameter_sort", 1);
        boolean is_required = MallUtil.getBoolean(request, "is_required", false);
        Document document = new Document();
        document.append("parameter_id", String.valueOf(System.currentTimeMillis()));
        document.append("parameter_name", parameter_name);
        document.append("parameter_sort", parameter_sort);
        document.append("is_required", is_required);
        document.append("variety_id", variety_id);
        document.append("company_id", SecurityUtils.getCompanyId());
        boolean b = productParameterRepository.create(document);
        resultMap.put("result", b);
        resultMap.put("msg", b ? "保存成功" : "保存失败");
        return new ResponseEntity(resultMap, HttpStatus.OK);
    }

    /**
     * 根据id删除宝贝参数
     *
     * @param parameter_id
     * @return
     */
    @Override
    public ResponseEntity deleteProductParameter(HttpServletRequest request, String parameter_id) {
        int companyId = MallUtil.getCompanyId(request);
        Bson filter = Filters.eq("parameter_id", parameter_id);
        String parameter = this.getProductParameterByFilter(filter);
        Map<String, Object> resultMap = new HashMap<>(2);
        if (StringUtils.isBlank(parameter)) {
            resultMap.put("result", false);
            resultMap.put("msg", "宝贝参数不存在或已被删除，删除失败");
            return new ResponseEntity(resultMap, HttpStatus.OK);
        }
        boolean b = productParameterRepository.delParameter(filter);
        // 修改商品身上参数信息
        this.updateCommodity(companyId, parameter_id, 2);
        resultMap.put("result", b);
        resultMap.put("msg", b ? "删除成功" : "删除失败");
        return new ResponseEntity(resultMap, HttpStatus.OK);
    }

    /**
     * 根据条件查询宝贝参数
     *
     * @param filter
     * @return
     */
    @Override
    public String getProductParameterByFilter(Bson filter) {
        return productParameterRepository.getProductParameter(filter);
    }

    /**
     * 更新宝贝参数数据
     *
     * @param request
     * @return
     */
    @Override
    public ResponseEntity updateProductParameter(HttpServletRequest request) {
        int companyId = MallUtil.getCompanyId(request);
        String parameter_id = MallUtil.getString(request, "parameter_id", "");
        String variety_id = MallUtil.getString(request, "variety_id", "");
        VarietyEntity varietyEntity = varietyService.getVarietyById(Filters.or(Filters.eq("variety_id", variety_id), Filters.eq("secondVarietyList.second_variety_id", variety_id)));
        Map<String, Object> resultMap = new HashMap<>(2);
        if (varietyEntity == null) {
            resultMap.put("result", false);
            resultMap.put("msg", "所属宝贝分类不存在或已被删除，更新失败");
            return new ResponseEntity(resultMap, HttpStatus.OK);
        }
        Bson filter = Filters.and(Filters.eq("parameter_id", parameter_id), Filters.eq("variety_id", variety_id));
        String parameter = this.getProductParameterByFilter(filter);
        if (StringUtils.isBlank(parameter)) {
            resultMap.put("result", false);
            resultMap.put("msg", "宝贝参数不存在或已被删除，更新失败");
            return new ResponseEntity(resultMap, HttpStatus.OK);
        }
        String parameter_name = MallUtil.getString(request, "parameter_name", "");
        Integer parameter_sort = MallUtil.getInteger(request, "parameter_sort", 1);
        boolean is_required = MallUtil.getBoolean(request, "is_required", false);
        Document document = Document.parse(parameter);
        document.append("parameter_name", parameter_name);
        document.append("parameter_sort", parameter_sort);
        document.append("is_required", is_required);
        boolean b = productParameterRepository.updateProductParameter(filter, document, false);
        // 修改商品身上参数信息
        this.updateCommodity(companyId, parameter_id, 1);
        resultMap.put("result", b);
        resultMap.put("msg", b ? "更新成功" : "更新失败");
        return new ResponseEntity(resultMap, HttpStatus.OK);
    }

    /**
     * 根据参数id，修改商品关于该参数的信息
     * @param parameter_id 参数id
     * @param state 状态码，1：修改  2：删除
     */
    private void updateCommodity(int companyId, String parameter_id, int state) {
        // 获取需要改修的商品内容
        Document filter = new Document("parameter.parameter_id", parameter_id);
        Document project = new Document("parameter", 1).append("commodity_id", 1);
        List<String> list = commodityRepository.findListAndProject(companyId, filter, project);
        if (CollectionUtils.isEmpty(list)) return;
        ProductParameterEntity parameter;
        Gson gson = new Gson();
        // 1 : 修改，获取修改的内容 2：删除，只需要id，就可以根据id过滤掉原数据
        if (state == 1) {
            // 获取当前参数内容
            String result = productParameterRepository.getProductParameter(new Document("parameter_id", parameter_id));
            if (StringUtil.isBlank(result)) return;
            parameter = gson.fromJson(result, ProductParameterEntity.class);
        } else {
            parameter = new ProductParameterEntity();
            parameter.setParameter_id(parameter_id);
        }
        for (String info : list) {
            CommodityEntity entity = gson.fromJson(info, CommodityEntity.class);
            if (CollectionUtils.isEmpty(entity.getParameter())) break;
            this.updateCommodityParameter(entity, parameter, state);
        }
    }

    /**
     * 更改商品参数
     * @param entity 商品信息
     * @param parameter 参数信息
     * @param state 状态码，1：修改  2：删除
     */
    private void updateCommodityParameter(CommodityEntity entity, ProductParameterEntity parameter, int state) {
        // 商品参数旧字段数据
        Map map = new HashMap();
        // 商品参数需要更新的数据
        List<Document> listDocument = new ArrayList<>();
        Gson gson = new Gson();
        for (ProductParameterEntity info : entity.getParameter()) {
            if (parameter.getParameter_id().equals(info.getParameter_id()) && state == 1) {
                info.setIs_required(parameter.getIs_required());
                info.setParameter_name(parameter.getParameter_name());
                info.setParameter_sort(parameter.getParameter_sort());
            }
            if (parameter.getParameter_id().equals(info.getParameter_id()) && state == 2) break;
            if (!StringUtils.isBlank(info.getContent())) map.put(info.getParameter_name(),info.getContent());
            listDocument.add(Document.parse(gson.toJson(info)));
        }
        // 更新商品信息
        Document filter = new Document("commodity_id", entity.getCommodity_id());
        Document doc = new Document("props", map).append("parameter", listDocument);
        commodityRepository.updateOneCommodity(entity.getCompany_id(), filter, doc, false);
    }

}
